#include "IRender.h"

struct FpsRender : IRender
{
	FpsRender(const dxres& res) :
		IRender(res)
	{
		LARGE_INTEGER freq;
		VERIFY(QueryPerformanceFrequency(&freq));

		m_freq = freq.QuadPart;
	}

	void Render() override
	{		
		CheckAndUpdateLayout();

		if (m_enableFps)
		{
			D2D1_SIZE_F size = m_res.target->GetSize();

			DWRITE_TEXT_METRICS metrics;
			HR(m_layout->GetMetrics(&metrics));
		
			D2D1_POINT_2F location = Point2F(size.width - metrics.width, 
											 0);

			m_res.target->DrawTextLayout(location,
										 m_layout.Get(), 
										 m_brush.Get());
		}
	}

	void CheckAndUpdateLayout()
	{
		LARGE_INTEGER qpc;
		VERIFY(QueryPerformanceCounter(&qpc));

		double ellapsed = 1.0 * (qpc.QuadPart - m_lastQpc) / m_freq;

		++m_frames;
		if (ellapsed > 1.0)
		{
			// Reset lastQpc
			double fps = m_frames / ellapsed;
			m_lastQpc = qpc.QuadPart;
			m_frames = 0;

			// UpdateLayout
			UpdateLayout(fps);
		}
	}

	void UpdateLayout(double fps)
	{
		wchar_t text[24];
		int length = swprintf_s(text, L"FPS: %.2f", fps);
		
		
		HR(m_res.dwrite->CreateTextLayout(text, 
										  length, 
										  m_format.Get(), 
										  1000.0f, 
										  1000.0f, 
										  m_layout.ReleaseAndGetAddressOf()));
	}

	void CreateDeviceResources() override
	{
		HR(m_res.target->CreateSolidColorBrush(ColorF(ColorF::White), 
											   m_brush.ReleaseAndGetAddressOf()));
	}

	void ReleaseDeviceResources() override
	{
		m_brush.Reset();
	}

	void CreateDeviceIndependentResources() override
	{
		HR(m_res.dwrite->CreateTextFormat(L"Consolas", 
										  nullptr, 
										  DWRITE_FONT_WEIGHT_NORMAL, 
										  DWRITE_FONT_STYLE_NORMAL, 
										  DWRITE_FONT_STRETCH_NORMAL, 
										  18.0f, 
										  L"", 
										  m_format.GetAddressOf()));
	}

	LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) override
	{
		if (message == WM_KEYUP)
		{
			if (wparam == 'P')
			{
				m_enableFps = !m_enableFps;
			}
		}

		return 0;
	}

	ComPtr<IDWriteTextFormat> m_format;
	ComPtr<IDWriteTextLayout> m_layout;
	ComPtr<ID2D1SolidColorBrush> m_brush;

	int m_frames;
	long long m_lastQpc = 0;
	long long m_freq;
	bool m_enableFps = true;
};